package controllers

import (
	"backend/form"
	"backend/models"
	"backend/services"
	"backend/utils"
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
)

type UserController struct {
	service *services.UserService
}

type UserResp struct {
	Id             uint                `json:"id"`
	UserName       string              `json:"username"`
	Email          string              `json:"email"`
	Avatar         string              `json:"avatar"`
	CreatedAt      string              `json:"created_at"`
	UpdatedAt      string              `json:"updated_at"`
	Token          string              `json:"token,omitempty"`
	Status         bool                `json:"status"`
	Supper         bool                `json:"supper"`
	PermissionMap  map[string][]string `json:"permission_map"`
	MenuPermission []*form.MenuTree    `json:"menu_permission"`
	Actions        []string            `json:"actions"`
}

type ResponseData struct {
	Code int    `json:"code"`
	Msg  string `json:"message"`
	Data struct {
		AccessToken      string `json:"access_token"`
		RefreshToken     string `json:"refresh_token"`
		TokenType        string `json:"token_type"`
		ExpiresIn        int    `json:"expires_in"`
		RefreshExpiresIn int    `json:"refresh_expires_in"`
		Scope            string `json:"scope"`
	} `json:"data"`
}

type GroupBindUserForm struct {
	GroupIds []uint `json:"group_ids"`
	UserId   uint   `json:"user_id"`
	Action   string `json:"action"` //bind,ubind
}

func NewUserController(s *services.UserService) *UserController {
	return &UserController{service: s}
}

// 增加用户
func (u *UserController) CreateUser(c *gin.Context) {
	var user models.User
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}
	if err := u.service.CreateUser(&user); err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(201, UserResp{
		Id:       user.ID,
		UserName: user.Username,
		Email:    user.Email,
		Avatar:   user.Avatar,
	})
}

// 更新用户
func (u *UserController) UpdateUser(c *gin.Context) {
	var user models.User
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}
	uuid, ok := c.Params.Get("id")
	if !ok {
		c.JSON(400, gin.H{"error": "参数错误"})
		return
	}

	//查找用户
	existingUser, err := u.service.GetUser(uuid)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	existingUser.ID = user.ID
	existingUser.Username = user.Username
	existingUser.Email = user.Email
	existingUser.Avatar = user.Avatar
	if err := u.service.UpdateUser(uuid, &user); err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(200, UserResp{
		Id:        user.ID,
		UserName:  user.Username,
		Email:     user.Email,
		Avatar:    user.Avatar,
		CreatedAt: existingUser.CreatedAt.String(),
	})
}

// 获取用户
func (U *UserController) GetUser(c *gin.Context) {
	uuid, ok := c.Params.Get("uuid")
	if !ok {
		c.JSON(400, gin.H{"error": "参数错误"})
		return
	}

	user, err := U.service.GetUser(uuid)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(200, UserResp{
		Id:       user.ID,
		UserName: user.Username,
		Email:    user.Email,
		Avatar:   user.Avatar,
		Status:   user.Status,
		Supper:   user.Supper,
	})
}

// 删除用户
func (U *UserController) DeleteUser(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(400, gin.H{"error": "参数错误"})
		return
	}
	if err := U.service.DeleteUser(id); err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	c.JSON(200, gin.H{"message": "success"})
}

// 禁用启用用户
type DisableUserRequest struct {
	Id      []uint `json:"id"`
	Disable bool   `json:"disable"`
}

func (U *UserController) DisableUser(c *gin.Context) {
	var disableUser DisableUserRequest
	if err := c.ShouldBindJSON(&disableUser); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	if err := U.service.DisableUser(disableUser.Id, disableUser.Disable); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"err": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"success": true})
}

// 获取全部用户
func (U *UserController) GetUserList(c *gin.Context) {
	pageInfo, err := models.GetPageInfo(c)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	username := c.Query("username")
	email := c.Query("email")

	users, count, err := U.service.GetUserList(pageInfo, &models.User{Username: username, Email: email})
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	usersResp := []UserResp{}
	for _, user := range users {
		usersResp = append(usersResp, UserResp{
			Id:        user.ID,
			UserName:  user.Username,
			Email:     user.Email,
			Avatar:    user.Avatar,
			CreatedAt: user.CreatedAt.String(),
			UpdatedAt: user.UpdatedAt.String(),
			Status:    user.Status,
			Supper:    user.Supper,
		})
	}

	c.JSON(200, gin.H{"data": usersResp, "success": true, "code": 200, "page": pageInfo.Page, "size": pageInfo.Size, "total": count})
}

func (U *UserController) Login(c *gin.Context) {
	var user models.User
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(400, gin.H{"error": err.Error()})
		return
	}

	if user.Email == "" || user.Password == "" {
		c.JSON(400, gin.H{"error": "参数错误"})
		return
	}
	if err := U.service.Login(&user); err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	token, err := utils.GenerateToken(user.Email)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	userresp := UserResp{
		Token: token,
	}
	var userData *models.User
	userData, err = U.service.GetUserPermission(user.Email)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	//列出所有加入的角色
	roleIDs := []uint{}

	// 累积所有组的角色权限
	permissionMap := make(map[string][]string) // method => paths
	actions := []string{}
	for _, group := range userData.Groups {
		for _, role := range group.Roles {
			roleIDs = append(roleIDs, role.ID) //组合所有角色id
			for _, permission := range role.Permissions {
				if permission.Path == "/user/list" {
					fmt.Println(permission.Path)
				}
				permissionMap[permission.Method] = append(permissionMap[permission.Method], permission.Path)
				actions = append(actions, permission.Action)
			}
		}
	}

	menuPermissionData, err := services.GetMenuTree(roleIDs, userData.Supper)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err})
		return
	}

	userRedisData := form.UserReids{
		PermissionMap:  permissionMap,
		Supper:         userData.Supper,
		Status:         userData.Status,
		MenuPermission: menuPermissionData,
		Actions:        actions,
	}
	// 将 UserReids 数据序列化为 JSON 字符串
	userRedisDataJSON, err := json.Marshal(userRedisData)
	if err != nil {
		c.JSON(500, gin.H{"error": "序列化失败"})
		return
	}
	utils.RDB.Set(c.Request.Context(), user.Email, userRedisDataJSON, 0)
	userresp.MenuPermission = menuPermissionData
	userresp.PermissionMap = permissionMap
	userresp.Status = userData.Status
	userresp.Supper = userData.Supper
	userresp.Email = userData.Email
	userresp.UserName = userData.Username
	userresp.Avatar = userData.Avatar
	userresp.CreatedAt = userData.CreatedAt.String()
	userresp.UpdatedAt = userData.UpdatedAt.String()
	userresp.Actions = actions
	userresp.Id = userData.ID
	c.JSON(200, gin.H{"data": userresp, "success": true, "code": 200})
}

func (u *UserController) GetUserBindGroupList(c *gin.Context) {

	user_id, err := models.GetParamsInt(c, "id")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}

	pageinfo, err := models.GetPageInfo(c)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	name := c.Query("name")
	group, err := u.service.GetUserBindGroupList(uint(user_id), pageinfo, &models.Group{Name: name})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"err": err.Error()})
		return
	}
	groups := []GroupResp{}
	for _, item := range group {
		groups = append(groups, GroupResp{
			Id:   item.ID,
			Name: item.Name,
			Desc: item.Desc,
		})
	}
	c.JSON(http.StatusOK, gin.H{"data": groups})
}

func (u *UserController) BindUserGroup(c *gin.Context) {
	userbindgroup := &GroupBindUserForm{}
	if err := c.ShouldBindJSON(userbindgroup); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"err": err.Error()})
		return
	}
	if err := u.service.BindUserGroup(userbindgroup.UserId, userbindgroup.GroupIds, userbindgroup.Action); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"err": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"data": ""})
}

func (U *UserController) Logout(c *gin.Context) {

}

func (U *UserController) FeiShuLogin(c *gin.Context) {
	var login_code map[string]string
	c.ShouldBindJSON(&login_code)
	code := login_code["code"]
	//获取access token
	body := map[string]string{
		"app_id":     "cli_a649b8920936d00c",
		"app_secret": "c8tUZkLecO8dU2aJnDUDJcpva5Blt1PV",
	}
	jsonData, err := json.Marshal(body)
	if err != nil {
		log.Fatalf("Failed to marshal JSON: %v", err)
	}
	req, err := http.NewRequest("POST", "https://open.feishu.cn/open-apis/auth/v3/app_access_token/internal", bytes.NewBuffer(jsonData))
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}
	req.Header.Add("Content-Type", "application/json; charset=utf-8")

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	defer resp.Body.Close()

	repbody, err := io.ReadAll(resp.Body)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	var result map[string]interface{}

	err = json.Unmarshal(repbody, &result)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	//获取用户访问token
	token_body := map[string]string{
		"grant_type": "authorization_code",
		"code":       code,
	}
	token_josn, err := json.Marshal(token_body)
	if err != nil {
		log.Fatalf("Failed to marshal JSON: %v", err)
	}

	req1, err := http.NewRequest("POST", "https://open.feishu.cn/open-apis/authen/v1/oidc/access_token", bytes.NewBuffer(token_josn))
	req1.Header.Add("Authorization", "Bearer "+result["app_access_token"].(string))
	req1.Header.Add("Content-Type", "application/json; charset=utf-8")
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	resp, err = http.DefaultClient.Do(req1)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	defer resp.Body.Close()

	repbody, err = io.ReadAll(resp.Body)

	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	var respdata ResponseData
	err = json.Unmarshal(repbody, &respdata)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	req2, _ := http.NewRequest("GET", "https://open.feishu.cn/open-apis/authen/v1/user_info", nil)
	req2.Header.Add("Authorization", "Bearer "+respdata.Data.AccessToken)
	resp3, _ := http.DefaultClient.Do(req2)
	defer resp3.Body.Close()

	repbody, err = io.ReadAll(resp3.Body)
	if err != nil {
		c.JSON(500, gin.H{"error": err.Error()})
		return
	}

	var userinfo map[string]interface{}
	json.Unmarshal(repbody, &userinfo)

	token, _ := utils.GenerateToken(userinfo["data"].(map[string]interface{})["name"].(string))
	time.Sleep(time.Second * 3)
	c.JSON(200, gin.H{"data": UserResp{
		Token:    token,
		UserName: userinfo["data"].(map[string]interface{})["name"].(string),
	}, "success": true, "code": 200})

}
